
import java.awt.*
import java.awt.event.*
import net.miginfocom.swing.MigLayout
import javax.swing.*
import javax.swing.event.*
import javax.swing.tree.*
import javax.swing.tree.DefaultMutableTreeNode as TreeNode
import javax.swing.table.*
import javax.swing.event.TableModelListener
import net.sshiffon.*

actions {

	action(id: "connectAction",
			name: "Connect",
			mnemonic: "C",
			enabled: bind {model.readyToConnect},
//			accelerator: shortcut("C"),
			closure: {
			    controller.showConnect(
			    		group.selectedItem,connectionName.text
			    		)
            })
	action(id: "clearAction",
			name: "Clear",
			mnemonic: "X",
			enabled: bind { ((!model?.empty) || (model?.readyToConnect)) }, //ensure you cant clear a connected item
			closure: {
				savedConnections.clearSelection()
				model.currentSetting.fromMap(new ConnectionSetting().toMap())
				connectionName.text=''
				user.requestFocus()
            })
	action(id: "saveAction",
		enabled: bind {model?.readyToSave},
		name: "Save",
		mnemonic: "S",
//		accelerator: shortcut ("S"),
		closure: {
			model.currentSetting.tunnels= model.tunnels
			app.controllers.Sshiffon.save(group.selectedItem,connectionName.text,model.currentSetting)
		})
	action(id: "saveAndConnectAction",
		enabled: bind { ((model?.readyToSave) && (model?.readyToConnect)) },
		name: "Save & Go",
		closure: {
			saveAction.closure()
			connectAction.closure()
		})
	
	action(id: 'addGroupAction', 
				name: 'Add Group', 
				closure: {
                        	def groupName= JOptionPane.showInputDialog("Group name")
                        	if(groupName!=null )
                        	{
                        		controller.addGroup(groupName)
                        	}
                        })
	action(id: 'deleteAction', 
			name:'Delete',
			mnemonic: "D",
			enabled: bind {model.connectionSelected},
	//		accelerator: shortcut ("D"),
			closure: {
                TreePath[] paths = savedConnections.getSelectionPaths()
                paths.each({ path ->
                    if(path != null)
                    {
                        controller.delete(path.getPath())
                    }
                })
			})

			action(id: "terminalAction",
					//name: "Terminal",
					mnemonic: "T",
					enabled: false,
		//			accelerator: shortcut("T"),
					closure: {
						logger.debug('ok')
						controller.initialiseShell()
						mainPanel.layout.show( view.mainPanel, "terminalCard" )
						controller.setDisableOnly('Terminal')
						doLater {
							model.termGroup?.view?.terminalPanel?.requestFocusInWindow()
						}
		            })

	action(id: 'addTunnelAction', 
				name: 'Add', 
				enabled: bind {model.readyToAddTunnel},
    			closure: { 
					controller.addTunnel(localPort.text,remoteHost.text,remotePort.text);
					localPort.text=''
					remoteHost.text=''
					remotePort.text=''
    			} )
}



panel(id: 'rootPanel', layout: new MigLayout("fill, ins 0")) {

	
	splitPane(id: 'splitPane', constraints: 'grow') 
	{

		panel(id:'savedConnectionsPanel',layout:  new MigLayout("fill, ins 0")) 
		{
			toolBar(constraints:'north')
			{
		        button(action: addGroupAction, icon: imageIcon('/crystal16/folder_new.png'), toolTipText: 'Add Group')
		        button(action: deleteAction, icon: imageIcon('/crystal16/delete.png'), toolTipText: 'Delete')
			}

			label('Saved Connections',constraints:"north", font: rootPanel.font.deriveFont(16.0f))
			
			tree(rootVisible: false,id:"savedConnections",constraints:"grow"){}
	
			savedConnections.setCellRenderer({ JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus ->
				if (leaf && !value.parent.isRoot()) {
					return label(value.toString(), icon:imageIcon('/crystal16/connect_no.png'))
				} else {
					return label(value.toString(), icon:imageIcon('/crystal16/folder.png'))
				}
			    } as javax.swing.tree.TreeCellRenderer)
			
			savedConnections.addTreeSelectionListener({  evt ->
				TreePath[] paths = savedConnections.getSelectionPaths();
				model.connectionSelected = (paths!=null && paths.length>0 && !paths[0].getLastPathComponent().equals("Main"));
			
			    paths.each({ path ->
			    if(path!=null)
			    {
			        controller.load(path.getPath())
			    }})
			} as javax.swing.event.TreeSelectionListener);
			savedConnections.addKeyListener( { evt ->
			    int keyCode = evt.getKeyCode();
			    String keyText = KeyEvent.getKeyText(keyCode);
			    if(keyCode == 10 && evt.getID()==KeyEvent.KEY_RELEASED)
			    {
			        logger.debug("Released ${keyCode} ${keyText}")
			        TreePath[] paths = savedConnections.getSelectionPaths();
			        paths.each({ path ->
			            if(path!=null)
			            {
			                def pathElements= path.getPath()
			                if (pathElements.length == 3)
			                {
			                    connectAction.closure()
			                }
			            }
			    }) }} as KeyListener)
			savedConnections.addMouseListener({ evt ->
			   if(evt.getID()==MouseEvent.MOUSE_CLICKED) {
				   TreePath[] paths = savedConnections.getSelectionPaths();
			    	if(paths!=null&& paths.length>0)
			    	{
			    		//connect
			    		TreePath path= paths[0]
			            if(evt.getClickCount() == 2 && !evt.isConsumed()) {
			                evt.consume();
			                def pathElements= path.getPath()
			                if (pathElements.length == 3)
			                {
			                	connectAction.closure()
			                }
			            }
			        }
			   }
			} as java.awt.event.MouseListener);
		}
		
		panel(id:'connectionConfigPanel',constraints:"grow", layout: new MigLayout("fill, insets 0"), background: Color.WHITE) {
			separator()
			panel(constraints:"grow",layout: new MigLayout("fill, insets 0"), opaque: false) {
			label("Connection Settings",font: rootPanel.font.deriveFont(15.0f),constraints:'north')
		
			label('Credentials',font: rootPanel.font.deriveFont(15.0f))
		    
		    panel(layout:new MigLayout("fill, insets 2"), opaque: false) {
		          label('User')
		          label('')
		          label('Host')
		          label('')
		          label('Port',constraints:'wrap')
		          textField(id:'user', columns:10, text: bind (
		          		target: model.currentSetting, targetProperty: 'user', 
		      	  		//source: model.settingFromPicker, sourceProperty: 'user' 
		          		mutual: true),
		      	  		enabled: bind{ !model.connected }
		      	  		)
		          label('@')
		          textField(id:'host', columns:20, text: bind (
		          		target: model.currentSetting, targetProperty: 'host', 
//		      	  		source: model.settingFromPicker, sourceProperty: 'host' ),
		          		mutual: true),
		      	  		enabled: bind{ !model.connected })
		          label(':')
		          textField(id:'port', columns:2,text:bind (
		          		target: model.currentSetting, targetProperty: 'port', 
		      	  		//source: model.settingFromPicker, sourceProperty: 'port' ),
		          		mutual: true),
		      	  		enabled: bind{ !model.connected }, constraints:'wrap')
		    }
		
		    panel(layout: new MigLayout("fill, insets 2"),constraints:'wrap', opaque: false) {
		              button(action: connectAction, icon: imageIcon('/crystal16/connect_creating.png'), constraints:'wrap')
		              button(action: clearAction, icon: imageIcon('/crystal16/editclear.png') , constraints:'wrap')
		    }
		      
		      label('Save As',font: connectionConfigPanel.font.deriveFont(15.0f))
		      
		      panel(layout: new MigLayout("fill, insets 2"), opaque: false) {
		            	  label('Group')
		                  comboBox(id:'group')
		                  label('Nickname')
		                  textField(id:'connectionName', columns:10)
		      }
		      panel(layout: new MigLayout("fill, insets 2"),constraints:"wrap", opaque: false) {
		    	  button(saveAction, icon: imageIcon('/crystal16/filesave.png'),constraints:'wrap')
		    	  button(saveAndConnectAction, icon: imageIcon('/crystal16/filesave.png'))
		      }
		      label('Start in',font: connectionConfigPanel.font.deriveFont(15.0f))
		      panel(constraints:'wrap',layout:new MigLayout("fill, insets 2"), opaque: false)
			  {
		    	  comboBox(id:'initialView',items:['Shell','Sftp','Config'],constraints:"wrap", 
		    			  selectedItem: bind(
		    					  target: model.currentSetting, targetProperty: 'initialView',
		    					 // source: model.settingFromPicker, sourceProperty:'initialView'
		    					  mutual: true
		    					  )
		    			  )
			  }
		      label('Keepalive',font: rootPanel.font.deriveFont(15.0f))
		      panel(constraints:'wrap',layout:new MigLayout("fill, insets 2"), opaque: false)
			  {  
		        checkBox(id:'isKeepAlive', selected: bind ( 
		        		target: model.currentSetting, targetProperty: 'isKeepAlive', 
		    	  		//source: model.settingFromPicker, sourceProperty: 'isKeepAlive'
		        		mutual: true
		    	  			))		                
		        label('every')
		        textField(id:'keepAliveSeconds', columns:4, text: bind (
				target: model.currentSetting, targetProperty: 'keepAliveSeconds', 
		  		//source: model.settingFromPicker, sourceProperty: 'keepAliveSeconds'
				mutual: true
		  			)
		        )
		        label('seconds',constraints:'wrap')
			  }
		      label('Terminal colours',font: rootPanel.font.deriveFont(15.0f))
		      panel(constraints:'wrap', layout: new MigLayout("fill, insets 2"), opaque: false) {
			        buttonGroup(id:'lookNFeel' ).with { group ->  
			        	panel(border: etchedBorder(), opaque: false)
						{
			        		button(  action:  action(name:'background:', closure: { Color c= JColorChooser.showDialog(app.views.Sshiffon.sshiffon, "Background Color", new Color(Integer.parseInt(backgroundcolor.text))); if(c){backgroundcolor.text= c.getRGB();bgLabel.background= c} }))
			        		label(id:'bgLabel',opaque:true,  text: "    ", border: etchedBorder())
			        		textField(id:'backgroundcolor', columns:0, visible:false, text: 
			        		bind ( 
			                		target: model.currentSetting, targetProperty: 'backgroundcolor', 
			            	  		//source: model.settingFromPicker, sourceProperty: 'backgroundcolor'
			                		mutual: true
			            	  			) )
						}
			        	
			        	panel(border: etchedBorder(), opaque: false)
						{
			        		button(  action:  action(name:'foreground:', closure: { Color c= JColorChooser.showDialog(app.views.Sshiffon.sshiffon, "Background Color", new Color(Integer.parseInt(foregroundcolor.text))); if(c){foregroundcolor.text= c.getRGB();fgLabel.background= c} }))
			        		label(id:'fgLabel',opaque:true,  text: "    ", border: etchedBorder())
				        	textField(id:'foregroundcolor', columns:0, visible:false, text:  
				        		bind ( 
				                		target: model.currentSetting, targetProperty: 'foregroundcolor', 
//				            	  		source: model.settingFromPicker, sourceProperty: 'foregroundcolor'
				                		mutual: true
				            	  			) )
						}
			            button( action: action(name:'Flip colours',
			            		closure: { def newBg=model.currentSetting.foregroundcolor 
			            		model.currentSetting.foregroundcolor=model.currentSetting.backgroundcolor;  
			            		model.currentSetting.backgroundcolor=newBg }))
			        }
		      }
			
		      label('Tunnels', font: connectionConfigPanel.font.deriveFont(15.0f))
		      scrollPane(constraints: "h 60, growx", id:'tunnelScrollPane') {
		          table(id: 'tunnels', constraints: 'grow', autoResizeMode: JTable.AUTO_RESIZE_ALL_COLUMNS, autoCreateColumnsFromModel: true, opaque:true, background: Color.WHITE) {
		          	current.selectionModel.addListSelectionListener({ evt -> 
		      	  	model.anyTunnelsSelected = !tunnels.selectionModel.selectionEmpty } as ListSelectionListener);

		              tableModel(list:model.tunnels)
		              {
		            	  //4 colums:
		            	  //locport
					     propertyColumn(headerValue:'Local Port', propertyName:'localPort' ,editable: false)
		            	  //remip
					     propertyColumn(headerValue:'Remote IP', propertyName:'remoteHost', editable: false)
		            	  //remport
					     propertyColumn(headerValue:'Remote Port', propertyName:'remotePort' ,editable: false)
		            	  //connected
					     propertyColumn(headerValue:'Enabled', propertyName:'enabled' ,editable: false)
		              }

		          }.addMouseListener({ evt -> if(evt.getClickCount() == 2 && !evt.isConsumed() && evt.getID()==java.awt.event.MouseEvent.MOUSE_CLICKED) {
		                          evt.consume();
		                          logger.debug("double clicked local file ${fileList.selectedRow} ${model.folderContents.get(fileList.selectedRow)}")
		                          controller.processEntry(model.folderContents.get(fileList.selectedRow))
		                        } } as java.awt.event.MouseListener);
		          }.metaClass.removeProppertyChangeListener= { x,y ->
		      			logger.debug("attempting to handle groovy bug here")
		      	};
		      tunnelScrollPane.viewport.background= Color.WHITE
		      
		      panel(constraints: "wrap",layout: new MigLayout("fill, insets 2"), opaque: false)
		      {
	                button(action: action(name: 'On/Off', enabled: bind {model.anyTunnelsSelected}, closure: {tunnels.selectedRows.each({controller.toggleTunnel(it)})}),constraints:'wrap')
	                button(action: action(name: 'Delete', enabled: bind{model.anyTunnelsSelected}, closure: {tunnels.selectedRows.each({controller.deleteTunnel(it)})}), icon: imageIcon('/crystal16/delete.png'))
	                //button(action: action(name: 'Untunnel', enabled: bind { tunnelList.selectedIndex > -1 }, closure: {controller.untunnel(tunnelList.getSelectedValue())}),constraints:'wrap')
	                //button(action: action(name: 'Refresh List', enabled: bind{ model.connected }, closure: {controller.loadTunnels()}), icon: imageIcon('/crystal16/reload.png'))
		      }
		      label('Add Tunnel', font: connectionConfigPanel.font.deriveFont(15.0f))
			      
		      panel(constraints: "",layout: new MigLayout("fill, insets 2"), opaque: false)
		      {
			      label('Local Port')
			      			textField(id:'localPort', columns:4)
			      label('Destination Address')
			                textField(id:'remoteHost', columns:10)
			      label('Destination Port')
			             	textField(id:'remotePort', columns:4)
		      }
		      panel(constraints: "wrap",layout: new MigLayout("fill, insets 2"), opaque: false)
		      {
		    	  	button(action: addTunnelAction,constraints:'wrap')
		      }
			}
		}
	}
	
	
}

reloadTunnels = {
    DefaultTableCellRenderer r = new DefaultTableCellRenderer()
    r.setHorizontalAlignment(JLabel.RIGHT)
    r.setFont( java.awt.Font.decode("Monospaced-10") )

    tunnels.model = tableModel(list:model.tunnels)
    {
    	  //locport
  	     propertyColumn(headerValue:'Local Port', propertyName:'localPort' ,editable: false)
    	  //remip
  	     propertyColumn(headerValue:'Remote IP', propertyName:'remoteHost', editable: false)
    	  //remport
  	     propertyColumn(headerValue:'Remote Port', propertyName:'remotePort' ,editable: false)
    	  //connected
  	     propertyColumn(headerValue:'Enabled', propertyName:'enabled' ,editable: false)
    }
}

controller.refreshConnectionsView()

bean( model, empty:bind { host.text=='' && user.text=='' && connectionName.text==''})
bean( model, readyToAddTunnel:bind {localPort.text!='' && remoteHost.text!='' && remotePort.text!=''})
bean( model, readyToSave:bind {host.text!='' && user.text!='' && connectionName.text!=''})
bean( model, readyToConnect:bind {host.text!='' && user.text!=''})
bean( bgLabel, background: bind { model.currentSetting.backgroundcolor ? new Color(new Integer(model.currentSetting.backgroundcolor)) : Color.BLACK } )
bean( fgLabel, background: bind { model.currentSetting.foregroundcolor ? new Color(new Integer(model.currentSetting.foregroundcolor)) : Color.WHITE } )

model.updateState(null) //initially dont specify a sub-view
user.requestFocus()
